<?php
namespace App\Services;

use App\Logic\LogLogic;
use Illuminate\Http\Client\RequestException;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Ramsey\Uuid\Uuid;
use Illuminate\Support\Facades\Http;

class BaoJianService {

    /**
     * @notes 获取唯一UUID
     * @return string
     * @author Evil丿
     * @date 2024/03/28 11:01
     */
    private static function getNonceStr()
    {
        $data = Uuid::uuid1(time());
        return $data->getHex()->toString();
    }

    /**
     * @notes 发起公共请求
     * @param $path
     * @param $data
     * @param $header
     * @return mixed
     * @throws RequestException
     * @author Evil丿
     * @date 2024/06/06 15:33
     */
    private static function commonRequest($path, $data)
    {
        $host = config('services.bj.host');

        $url = $host . $path;

        $header = [
            'Content-Type' => 'application/json',
            'appid'        => config('services.bj.appId'),
            'noncestr'     => self::getNonceStr(),
            'timestamp'    => time(),
        ];

        $header['sign'] = self::makeSign($header, $data);

        $response = Http::retry(3, 1000)
            -> timeout(3)
            -> withHeaders($header)
            -> post($url, $data)
            -> throw()
            -> json();

        if(!$response) {
            throw new AccessDeniedHttpException('BJ服务请求失败');
        }

        if($response['code'] != 20000) {
            throw new AccessDeniedHttpException($response['message']);
        }

        LogLogic::setBjLogs($header['noncestr'], $path, $data);

        if(!$response['data']) {
            $response['data'] = $response['code'];
        }

        return $response['data'];
    }

    /**
     * @notes 生成签名字符串
     * @param $params
     * @param $appSecret
     * @return string
     * @author Evil丿
     * @date 2024/06/06 15:33
     */
    public static function makeSign($header, $data)
    {
        $arr = [
            $header['appid'],
            config('services.bj.appKey'),
            $header['noncestr'],
            $header['timestamp'],
            json_encode($data, 259)
        ];

        $str = implode('&', $arr);

        return MD5($str);
    }


    public static function machineRegister($imei, $device_code)
    {
        $params = [
            "imei"              => $imei,
            "outDeviceCode"     => $device_code
        ];

        $path = '/ams/api/device/register';

        $res = self::commonRequest($path, $params);

        return $res;
    }

    public static function machineSetting($data)
    {
        $camera_list = [];

        foreach($data['cabinet_camera_list'] as $v) {
            $camera_list[] = [
                'cameraNo'       => (int) $v['camera_no'],
                'bitStream'      => (int) $v['bit_stream'],
                'frameRate'      => (int) $v['frame_rate'],
                'exposure'       => (int) $v['exposure'],
                'resolution'     => (int) $v['resolution'],
            ];
        }

        $params = [
            'deviceCode'        => $data['device_code'],
            'cabinetList'       => [
                [
                    'cabinetNo'     => 1,
                    'priorCameraNo' => (int) $data['upload_mode'],
                    'cameraList'    => $camera_list
                ]
            ]
        ];

        $path = '/ams/api/device/setting';

        $res = self::commonRequest($path, $params);

        return $res;
    }

    public static function volumeSetting($device_code, $media_volume)
    {
        $params = [
            'deviceCode'        => $device_code,
            'systemVolume'      => 100,
            'mediaVolume'       => $media_volume,
        ];
        $path = '/ams/api/device/volume';

        $res = self::commonRequest($path, $params);

        return $res;
    }


    public static function machineStatus($device_code)
    {
        $params = [
            'deviceCode'        => $device_code
        ];

        $path = '/ams/api/device/status';

        $res = self::commonRequest($path, $params);

        return $res;
    }

    public static function openDoor($device_code, $door_num, $event_type)
    {
        $params = [
            'deviceCode'     => $device_code,
            'cabinetNo'      => $door_num,
            'outOpenNo'      => MD5($device_code.$door_num.time()),
            'eventType'      => $event_type,
            'lockNotifyUrl'  => config('app.url').'/api/swt/notify/bj/door',
            'videoNotifyUrl' => config('app.url').'/api/swt/notify/bj/video',
        ];

        $path = '/ams/api/event/open';

        $res = self::commonRequest($path, $params);

        return $res;
    }

    public static function machineRestart($device_code)
    {
        $params = [
            'deviceCode'     => $device_code
        ];

        $path = '/ams/api/device/restart';

        $res = self::commonRequest($path, $params);

        return $res;
    }

    /**
     * @notes
     * 视频重传
     * @param $eventId
     * @return mixed
     * @throws RequestException
     * @author Evil丿
     * @date 2024/12/12 17:52
     */
    public static function uploadVideo($eventId) {
        $params = [
            'eventId'     => $eventId
        ];

        $path = '/ams/api/event/video';

        $res = self::commonRequest($path, $params);

        return $res;
    }
}
